/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
   Module Name          : com.yaodian100.ec.shopping.entity.CartOrders
   Module Description   :

   Date Created      : 2009/12/29
   Original Author   : ellen.li
   Team              : yaodian100
   ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
   MODIFICATION HISTORY
   ------------------------------------------------------------------------------
   Date Modified       Modified by       Comments
   ------------------------------------------------------------------------------
   ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
package com.yaodian100.ec.shopping.entity;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.OrderBy;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;

import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;
import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction;

import com.yaodian100.core.common.entity.BaseEntity;
import com.yaodian100.ec.creditcard.entity.CreditcardDetail;

/**
 * @author ellen.li
 * 
 */
@Entity
@Table(name = "EC_CART_ORDER_MAIN")
public class CartOrders extends BaseEntity {

	private static final long serialVersionUID = 5141666124818995805L;

	/**
	 * 購物車代碼, UUID
	 */
	@Id
	@GeneratedValue(generator = "assigned")
	@GenericGenerator(name = "assigned", strategy = "assigned")
	@Column(name = "cart_id", length = 50)
	private String cartId;

	/**
	 * 
	 */
	@Temporal(TemporalType.TIMESTAMP)
	@Column(name = "order_dt", nullable = false)
	private Date orderDt;

	/**
	 * 會員編號
	 */
	@Column(name = "member_id", length = 10)
	private String memberId;

	/**
	 * 會員帳號
	 */
	@Column(name = "login_id", length = 100)
	private String loginId;

	/**
	 * 會員名稱
	 */
	@Column(name = "member_name", length = 100)
	private String memberName;

	@Column(name = "receiver_name", length = 20)
	private String receiverName;

	@Column(name = "receiver_province", length = 20)
	private String receiverProvince;

	@Column(name = "receiver_city", length = 20)
	private String receiverCity;

	@Column(name = "receiver_area", length = 20)
	private String receiverArea;

	@Column(name = "receiver_zip", length = 10)
	private String receiverZip;

	@Column(name = "receiver_addr", length = 100)
	private String receiverAddr;

	@Column(name = "receiver_mobile", length = 20)
	private String receiverMobile;

	@Column(name = "receiver_phone_area", length = 10)
	private String receiverPhoneArea;

	@Column(name = "receiver_phone", length = 20)
	private String receiverPhone;

	@Column(name = "receiver_ext", length = 10)
	private String receiverExt;

	@Column(name = "receiver_email", length = 100)
	private String receiverEmail;

	/**
	 * 寄送方式, 預設 10
	 */
	@Column(name = "receiver_tp", length = 5)
	private String receiverTp = "10";

	/**
	 * 訂單金額(totalPrice-discount)
	 */
	@Column(name = "amount", nullable = false, columnDefinition = "numeric(10,2)")
	private BigDecimal amount = BigDecimal.ZERO;

	/**
	 * 折扣總額
	 */
	@Column(name = "discount", nullable = false, columnDefinition = "numeric(10,2)")
	private BigDecimal discount = BigDecimal.ZERO.setScale(1);

	/**
	 * 实收金额
	 */
	@Column(name = "cash", nullable = false, columnDefinition = "numeric(10,2)")
	private BigDecimal cash = BigDecimal.ZERO.setScale(1);

	/**
	 * 使用账户余额
	 */
	@Column(name = "my_wallet", nullable = false, columnDefinition = "numeric(10,2)")
	private BigDecimal myWallet = BigDecimal.ZERO.setScale(1);

	/**
	 * 礼券
	 */
	@Column(name = "coupon", nullable = false, columnDefinition = "numeric(10,2)")
	private BigDecimal coupon = BigDecimal.ZERO.setScale(1);

	/**
	 * 购物金
	 */
	@Column(name = "bonus", nullable = false, columnDefinition = "numeric(10,2)")
	private BigDecimal bonus = BigDecimal.ZERO.setScale(1);

	/**
	 * 福利金
	 */
	@Column(name = "benefit", nullable = false, columnDefinition = "numeric(10,2)")
	private BigDecimal benefit = BigDecimal.ZERO.setScale(1);

	/**
	 * 應付金額
	 */
	@Column(name = "must_pay", nullable = false, columnDefinition = "numeric(10,2)")
	private BigDecimal mustPay = BigDecimal.ZERO.setScale(1);

	/**
	 * 運費
	 */
	@Column(name = "shipfare", nullable = false, columnDefinition = "numeric(10,2)")
	private BigDecimal shipfare = BigDecimal.ZERO.setScale(1);

	/**
	 * 商品購買數
	 */
	@Transient
	private int productSum = 0;

	@Column(name = "channel", length = 20)
	private String channel;

	@Column(name = "channel_seq")
	private int channelSeq;

	@Column(name = "b2e_id", length = 20)
	private String b2eId;

	@Column(name = "memo", length = 300)
	private String memo;

	@Column(name = "client_ip", length = 20)
	private String clientIp;

	@Column(name = "payment_id", length = 20)
	private String paymentId;

	@OneToMany(targetEntity = CartOrderProduct.class, mappedBy = "cart", fetch = FetchType.EAGER)
	@Cascade({ CascadeType.SAVE_UPDATE, CascadeType.DELETE_ORPHAN })
	@OnDelete(action = OnDeleteAction.CASCADE)
	@OrderBy("prodSeq ASC, cartOrderProdId DESC")
	private List<CartOrderProduct> cartOrderProducts;

	/**
	 * 允许拆单 Y/N
	 */
	@Column(name = "allow_split", length = 1)
	private String allowSplit = "N";

	@Transient
	private Map<String, ApplyCampaign> applyCampaign;

	@Transient
	private CreditcardDetail creditcardDetail;

	@Transient
	private String period;

	@Transient
	private String invoiceTp;

	@Transient
	private String invoiceTitle;

	/** default constructor */
	public CartOrders() {
		super();
	}

	/** default constructor */
	public CartOrders(String memberId, String loginId) {
		super();
		this.cartId = memberId;
		this.memberId = memberId;
		this.loginId = loginId;
	}

	public CartOrders addCartOrderProduct(CartOrderProduct cop) {
		getCartOrderProducts().add(cop);
		cop.setCart(this);
		cop.setProdSeq(getCartOrderProducts().size());
		return this;
	}

	/**
	 * @return the applyCampaign
	 */
	public Map<String, ApplyCampaign> getApplyCampaign() {
		if (applyCampaign == null) {
			applyCampaign = new HashMap();
		}
		return applyCampaign;
	}

	/**
	 * @param applyCampaign the applyCampaign to set
	 */
	public void setApplyCampaign(Map<String, ApplyCampaign> applyCampaign) {
		this.applyCampaign = applyCampaign;
	}

	/**
	 * 不含運費
	 * 
	 * @return
	 */
	public BigDecimal getAmount() {
		amount = BigDecimal.ZERO.setScale(1);
		for (CartOrderProduct cop : getCartOrderProducts()) {
			// 效果與 sum(cop.totalPrice) 相同
			for (CartOrderProductDetail copd : cop.getDetails()) {
				// 计算金额
				if (copd.getAmount() != null) {
					amount = amount.add(copd.getAmount().multiply(BigDecimal.valueOf(copd.getQty())));
				}
			}
		}
		amount = amount.subtract(discount);
		return amount;
	}

	/**
	 * @return the cartOrderProducts
	 */
	public List<CartOrderProduct> getCartOrderProducts() {
		if (cartOrderProducts == null) {
			cartOrderProducts = new ArrayList();
		}
		return cartOrderProducts;
	}

	/**
	 * @return the weightSum
	 */
	@Transient
	public BigDecimal getWeightSum() {
		BigDecimal weight = BigDecimal.ZERO.setScale(3);
		for (CartOrderProduct cop : getCartOrderProducts()) {
			for (CartOrderProductDetail copd : cop.getDetails()) {
				// 计算重量
				if (copd.getWeight() != null) {
					weight = weight.add(copd.getWeight().multiply(BigDecimal.valueOf(copd.getQty())));
				}
			}
		}
		weight = weight.divide(BigDecimal.valueOf(1000).setScale(3));
		return weight;
	}

	@Transient
	private String version;

	/**
	 * @return the cartId
	 */
	public String getCartId() {
		return cartId;
	}

	/**
	 * @param cartId the cartId to set
	 */
	public void setCartId(String cartId) {
		this.cartId = cartId;
	}

	/**
	 * @return the orderDt
	 */
	public Date getOrderDt() {
		return orderDt;
	}

	/**
	 * @param orderDt the orderDt to set
	 */
	public void setOrderDt(Date orderDt) {
		this.orderDt = orderDt;
	}

	/**
	 * @return the memberId
	 */
	public String getMemberId() {
		return memberId;
	}

	/**
	 * @param memberId the memberId to set
	 */
	public void setMemberId(String memberId) {
		this.memberId = memberId;
	}

	/**
	 * @return the loginId
	 */
	public String getLoginId() {
		return loginId;
	}

	/**
	 * @param loginId the loginId to set
	 */
	public void setLoginId(String loginId) {
		this.loginId = loginId;
	}

	/**
	 * @return the memberName
	 */
	public String getMemberName() {
		return memberName;
	}

	/**
	 * @param memberName the memberName to set
	 */
	public void setMemberName(String memberName) {
		this.memberName = memberName;
	}

	/**
	 * @return the receiverName
	 */
	public String getReceiverName() {
		return receiverName;
	}

	/**
	 * @param receiverName the receiverName to set
	 */
	public void setReceiverName(String receiverName) {
		this.receiverName = receiverName;
	}

	/**
	 * @return the receiverProvince
	 */
	public String getReceiverProvince() {
		return receiverProvince;
	}

	/**
	 * @param receiverProvince the receiverProvince to set
	 */
	public void setReceiverProvince(String receiverProvince) {
		this.receiverProvince = receiverProvince;
	}

	/**
	 * @return the receiverCity
	 */
	public String getReceiverCity() {
		return receiverCity;
	}

	/**
	 * @param receiverCity the receiverCity to set
	 */
	public void setReceiverCity(String receiverCity) {
		this.receiverCity = receiverCity;
	}

	/**
	 * @return the receiverArea
	 */
	public String getReceiverArea() {
		return receiverArea;
	}

	/**
	 * @param receiverArea the receiverArea to set
	 */
	public void setReceiverArea(String receiverArea) {
		this.receiverArea = receiverArea;
	}

	/**
	 * @return the receiverZip
	 */
	public String getReceiverZip() {
		return receiverZip;
	}

	/**
	 * @param receiverZip the receiverZip to set
	 */
	public void setReceiverZip(String receiverZip) {
		this.receiverZip = receiverZip;
	}

	/**
	 * @return the receiverAddr
	 */
	public String getReceiverAddr() {
		return receiverAddr;
	}

	/**
	 * @param receiverAddr the receiverAddr to set
	 */
	public void setReceiverAddr(String receiverAddr) {
		this.receiverAddr = receiverAddr;
	}

	/**
	 * @return the receiverMobile
	 */
	public String getReceiverMobile() {
		return receiverMobile;
	}

	/**
	 * @param receiverMobile the receiverMobile to set
	 */
	public void setReceiverMobile(String receiverMobile) {
		this.receiverMobile = receiverMobile;
	}

	/**
	 * @return the receiverPhoneArea
	 */
	public String getReceiverPhoneArea() {
		return receiverPhoneArea;
	}

	/**
	 * @param receiverPhoneArea the receiverPhoneArea to set
	 */
	public void setReceiverPhoneArea(String receiverPhoneArea) {
		this.receiverPhoneArea = receiverPhoneArea;
	}

	/**
	 * @return the receiverPhone
	 */
	public String getReceiverPhone() {
		return receiverPhone;
	}

	/**
	 * @param receiverPhone the receiverPhone to set
	 */
	public void setReceiverPhone(String receiverPhone) {
		this.receiverPhone = receiverPhone;
	}

	/**
	 * @return the receiverExt
	 */
	public String getReceiverExt() {
		return receiverExt;
	}

	/**
	 * @param receiverExt the receiverExt to set
	 */
	public void setReceiverExt(String receiverExt) {
		this.receiverExt = receiverExt;
	}

	/**
	 * @return the receiverEmail
	 */
	public String getReceiverEmail() {
		return receiverEmail;
	}

	/**
	 * @param receiverEmail the receiverEmail to set
	 */
	public void setReceiverEmail(String receiverEmail) {
		this.receiverEmail = receiverEmail;
	}

	/**
	 * @return the receiverTp
	 */
	public String getReceiverTp() {
		return receiverTp;
	}

	/**
	 * @param receiverTp the receiverTp to set
	 */
	public void setReceiverTp(String receiverTp) {
		this.receiverTp = receiverTp;
	}

	/**
	 * @return the discount
	 */
	public BigDecimal getDiscount() {
		discount = BigDecimal.ZERO.setScale(1);
		for (CartOrderProduct cop : getCartOrderProducts()) {
			discount = discount.add(cop.getDiscount());
		}
		return discount;
	}

	/**
	 * @param discount the discount to set
	 * @deprecated 計算結果, 不需要 update
	 */
	@Deprecated
	public void setDiscount(BigDecimal discount) {
		getDiscount();
	}

	/**
	 * @return the cash
	 */
	public BigDecimal getCash() {
		return cash;
	}

	/**
	 * @param cash the cash to set
	 */
	public void setCash(BigDecimal cash) {
		this.cash = cash;
	}

	/**
	 * @return the shipfare
	 */
	public BigDecimal getShipfare() {
		return shipfare;
	}

	/**
	 * @param shipfare the shipfare to set
	 */
	public void setShipfare(BigDecimal shipfare) {
		this.shipfare = shipfare;
	}

	/**
	 * @return the channel
	 */
	public String getChannel() {
		return channel;
	}

	/**
	 * @param channel the channel to set
	 */
	public void setChannel(String channel) {
		this.channel = channel;
	}

	/**
	 * @return the channelSeq
	 */
	public int getChannelSeq() {
		return channelSeq;
	}

	/**
	 * @param channelSeq the channelSeq to set
	 */
	public void setChannelSeq(int channelSeq) {
		this.channelSeq = channelSeq;
	}

	/**
	 * @return the b2eId
	 */
	public String getB2eId() {
		return b2eId;
	}

	/**
	 * @param b2eId the b2eId to set
	 */
	public void setB2eId(String b2eId) {
		this.b2eId = b2eId;
	}

	/**
	 * @return the memo
	 */
	public String getMemo() {
		return memo;
	}

	/**
	 * @param memo the memo to set
	 */
	public void setMemo(String memo) {
		this.memo = memo;
	}

	/**
	 * @return the clientIp
	 */
	public String getClientIp() {
		return clientIp;
	}

	/**
	 * @param clientIp the clientIp to set
	 */
	public void setClientIp(String clientIp) {
		this.clientIp = clientIp;
	}

	/**
	 * @return the myWallet
	 */
	public BigDecimal getMyWallet() {
		return myWallet;
	}

	/**
	 * @param myWallet the myWallet to set
	 */
	public void setMyWallet(BigDecimal myWallet) {
		this.myWallet = myWallet;
	}

	/**
	 * @return the coupon
	 */
	public BigDecimal getCoupon() {
		return coupon;
	}

	/**
	 * @param coupon the coupon to set
	 */
	public void setCoupon(BigDecimal coupon) {
		this.coupon = coupon;
	}

	/**
	 * @return the bonus
	 */
	public BigDecimal getBonus() {
		return bonus;
	}

	/**
	 * @param bonus the bonus to set
	 */
	public void setBonus(BigDecimal bonus) {
		this.bonus = bonus;
	}

	/**
	 * @return the benefit
	 */
	public BigDecimal getBenefit() {
		return benefit;
	}

	/**
	 * @param benefit the benefit to set
	 */
	public void setBenefit(BigDecimal benefit) {
		this.benefit = benefit;
	}

	/**
	 * @return the mustPay
	 */
	public BigDecimal getMustPay() {
		mustPay = getAmount().add(getShipfare()).subtract(getBonus()).subtract(getBenefit()).subtract(getMyWallet());
		return mustPay;
	}

	/**
	 * @param mustPay the mustPay to set
	 */
	public void setMustPay(BigDecimal mustPay) {
		this.mustPay = mustPay;
	}

	/**
	 * @return the paymentId
	 */
	public String getPaymentId() {
		return paymentId;
	}

	/**
	 * @param paymentId the paymentId to set
	 */
	public void setPaymentId(String paymentId) {
		this.paymentId = paymentId;
	}

	/**
	 * @return the productSum
	 */
	public int getProductSum() {
		return productSum;
	}

	/**
	 * @param productSum the productSum to set
	 */
	public void setProductSum(int productSum) {
		this.productSum = productSum;
	}

	/**
	 * @param amount the amount to set
	 */
	public void setAmount(BigDecimal amount) {
		this.amount = amount;
	}

	/**
	 * @param cartOrderProducts the cartOrderProducts to set
	 */
	public void setCartOrderProducts(List<CartOrderProduct> cartOrderProducts) {
		this.cartOrderProducts = cartOrderProducts;
	}

	public String getVersion() {
		return version;
	}

	public void setVersion(String version) {
		this.version = version;
	}

	public Set<String> getJoinOrderSupplySet() {
		Set<String> supplySet = new HashSet();
		for (CartOrderProduct cop : getCartOrderProducts()) {
			if ("Y".equals(cop.getIsScm())) {
				supplySet.add(cop.getSupplierId());
			} else {
				// 不是 Y 表示入仓(N or B)
				supplySet.add("N");
			}
		}
		return supplySet;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return "CartOrders [cartId=" + cartId + ", memberId=" + memberId + ", amount=" + amount + ", discount=" + discount
				+ ", mustPay=" + mustPay + ", shipfare=" + shipfare + ", version=" + version + ", applyCampaign="
				+ applyCampaign + "]";
	}

	public CreditcardDetail getCreditcardDetail() {
		return creditcardDetail;
	}

	public void setCreditcardDetail(CreditcardDetail creditcardDetail) {
		this.creditcardDetail = creditcardDetail;
	}

	public String getPeriod() {
		return period;
	}

	public void setPeriod(String period) {
		this.period = period;
	}

	public String getInvoiceTp() {
		return invoiceTp;
	}

	public void setInvoiceTp(String invoiceTp) {
		this.invoiceTp = invoiceTp;
	}

	public String getInvoiceTitle() {
		return invoiceTitle;
	}

	public void setInvoiceTitle(String invoiceTitle) {
		this.invoiceTitle = invoiceTitle;
	}

	public String getAllowSplit() {
		return allowSplit;
	}

	public void setAllowSplit(String allowSplit) {
		this.allowSplit = allowSplit;
	}

}
